//
//  CalculatorModel.m
//  Calculator
//
//  Created by Wu Ting on 13-4-16.
//  Copyright (c) 2013年 Wu Ting. All rights reserved.
//

#import "CalculatorModel.h"
#import <math.h>

@interface CalculatorModel()
@property (nonatomic, strong) NSMutableArray *operandStack;

@end

@implementation CalculatorModel
@synthesize operandStack = _operandStack;

- (NSMutableArray *)operandStack {
    if (_operandStack == nil) _operandStack = [[NSMutableArray alloc] init];
    return _operandStack;
}

- (void) pushOperand:(double)operand {
    [self.operandStack addObject:[NSNumber numberWithDouble:operand]];
}

- (double) popOperand {
    NSNumber *operandObject = [self.operandStack lastObject];
    if (operandObject) [self.operandStack removeLastObject];
    return [operandObject doubleValue];
}

#define CASE(str) if ([__s__ isEqualToString:(str)])
#define SWITCH(s) for(NSString *__s__ = (s); ;)
#define DEFAULT

- (double) performOperation: (NSString *)operation {
    double result = 0;
    
    SWITCH(operation) {
        CASE(@"*") {
            result = [self popOperand] * [self popOperand];
            break;
        }
        CASE(@"/") {
            result = 1 / ([self popOperand] / [self popOperand]);
            break;
        }
        CASE(@"+") {
            result = [self popOperand] + [self popOperand];
            break;
        }
        CASE(@"-") {
            result = -([self popOperand] - [self popOperand]);
            break;
        }
        CASE(@"+/-") {
            double dig = [self popOperand];
            if (dig == 0) 
                result = dig; else result = -dig;
            break;
        }
        CASE(@"sin") {
            result = sin([self popOperand]);
            break;
        }
        CASE(@"cos") {
            result = cos([self popOperand]);
            break;
        }
        CASE(@"sqrt") {
            result = sqrt([self popOperand]);
            break;
        }
        CASE(@"log") {
            result = log([self popOperand]);
            break;
        }
        DEFAULT {
            break;
        }
    }
    
    [self pushOperand:result];
    return result;
}



@end
